package cn.xiuxius.embedded.command.preprocess;


import cn.xiuxius.embedded.config.EasyYamlConfig;
import cn.xiuxius.embedded.dependencyscan.DependencyAnalyzer;
import cn.xiuxius.embedded.dependencyscan.KeilFile;
import cn.xiuxius.embedded.keil.RTOS;
import cn.xiuxius.embedded.processor.RTX51TinyPreProcessor;
import lombok.extern.slf4j.Slf4j;
import picocli.CommandLine;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

@CommandLine.Command(name = "process",
        description = "Process command",
        mixinStandardHelpOptions = true
)
@Slf4j
public class ProcessCommand implements Callable<Integer> {

    @Override
    public Integer call() throws Exception {
        return doProcess();
    }

    @CommandLine.Option(
            names = {"-p", "--process-only"},
            description = "Only process dependencies, do not revivification.",
            defaultValue = "false"
    )
    private boolean processOnly = false;

    public int doProcess() {
        EasyYamlConfig config = EasyYamlConfig.load();
        if (config == null) {
            log.error("Failed to load easy-stc.yml.");
            return 1;
        }
        log.info("📄 Processing dependencies...");
        List<KeilFile> analyzeFiles = new ArrayList<>();
        try {
            if (config.getKeilProject().getRtos() != RTOS.NONE) {
                analyzeFiles.addAll(DependencyAnalyzer.collectLibAndA51Files(config.getKeilProject()));
            }
            analyzeFiles.addAll(DependencyAnalyzer.analyze(config.getKeilProject()));
        } catch (IOException e) {
            log.error("Failed to analyze dependencies.");
            return 1;
        }
        //用;隔开
        log.info("✔️ Dependencies processed.");
        log.info("Dependencies found: {}", analyzeFiles.size());
        if (config.getKeilProject().getRtos() != RTOS.NONE) {
            Callable<Boolean> revivification;
            log.info("RTOS mode: {}", config.getKeilProject().getRtos());
            log.info("Start Preprocessing...");
            RTX51TinyPreProcessor rtx51TinyPreProcessor = new RTX51TinyPreProcessor(analyzeFiles, true);
            if (processOnly) {
                log.info("Only process dependencies, do not revivification.");
                return rtx51TinyPreProcessor.doProcessOnly() ? 0 : 1;
            }

            revivification = rtx51TinyPreProcessor.doProcessWithRevivification();
            if (revivification == null) {
                log.error("Failed to preprocess.");
                return 1;
            } else {
                log.info("✔️ Preprocess completed.");
            }
            log.info("Start Revivification...");
            try {
                Boolean call = revivification.call();
                if (!call) {
                    log.error("Failed to revivify.");
                    return 1;
                }
            } catch (Exception e) {
                log.error("Failed to revivify.", e);
                return 1;
            }
        }
        log.info("✔️ Preprocess completed.");
        return 0;
    }

}
